﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace Noris.Tools.DbManager.Components
{
    /// <summary>
    /// Třída, která v sobě zahrnuje metody pro obecné renderování controlů na základě jejich zadání a stavu.
    /// </summary>
    public static class UiRenderer
	{
		#region Renderer
		public static void DrawBackground(Graphics graphics, RectangleF area, Color backColor, int colorShift, RenderStyle renderStyle, MouseState mouseState)
		{
            if (area.Width > 0f && area.Height > 0f)
            {
                using (LinearGradientBrush lgb = new LinearGradientBrush(area, backColor, backColor, 90f))
                {
                    lgb.InterpolationColors = GetColorBlend(backColor, colorShift, renderStyle, mouseState);
                    graphics.FillRectangle(lgb, area);
                }
            }
		}
		#endregion
		#region ColorBlend
		/// <summary>
		/// Vrátí objekt ColorBlend, který reprezentuje daný renderovací styl a stav myši (aktivitu objektu)
		/// </summary>
		/// <param name="colorRoot"></param>
		/// <param name="colorShift"></param>
		/// <param name="style"></param>
		/// <param name="state"></param>
		/// <returns></returns>
        public static ColorBlend GetColorBlend(Color colorRoot, int colorShift, RenderStyle style, MouseState state)
        {
            switch (style)
            {
                case RenderStyle.ProfessionalStyle:
                    return GetColorBlendProfessionalStyle(colorRoot, colorShift, state);
                case RenderStyle.WinXpStyle:
                    return GetColorBlendWinXpStyle(colorRoot, colorShift, state);
                case RenderStyle.Win7Style:
                    return GetColorBlendWin7Style(colorRoot, colorShift, state);
                case RenderStyle.FlatStyle:
                default:
                    return GetColorBlendFlatStyle(colorRoot, colorShift, state);
            }
        }

        private static ColorBlend GetColorBlendFlatStyle(Color colorRoot, float colorShift, MouseState state)
        {
            switch (state)
            {
                case MouseState.OnControl:
                case MouseState.MouseRightDown:
                    return new ColorBlend()
                    {
                        Positions = new float[] { 0f, 1f },
                        Colors = new Color[] { colorRoot.ShiftColor(0.85f * colorShift), colorRoot.ShiftColor(-0.20f * colorShift) }
                    };
                case MouseState.MouseLeftDown:
                    return new ColorBlend()
                    {
                        Positions = new float[] { 0f, 1f },
                        Colors = new Color[] { colorRoot.ShiftColor(-0.50f * colorShift), colorRoot.ShiftColor(0.50f * colorShift) }
                    };
                case MouseState.None:
                case MouseState.Outside:
                default:
                    return new ColorBlend()
                    {
                        Positions = new float[] { 0f, 1f },
                        Colors = new Color[] { colorRoot.ShiftColor(0.60f * colorShift), colorRoot.ShiftColor(-0.40f * colorShift) }
                    };
            }
        }

        private static ColorBlend GetColorBlendProfessionalStyle(Color colorRoot, float colorShift, MouseState state)
        {
            switch (state)
            {
                case MouseState.OnControl:
                case MouseState.MouseRightDown:
                    return new ColorBlend()
                    {
                        Positions = new float[] { 0f, 0.33f, 1f },
                        Colors = new Color[] { colorRoot.ShiftColor(0.85f * colorShift), colorRoot.ShiftColor(0.25f * colorShift), colorRoot.ShiftColor(-0.20f * colorShift) }
                    };
                case MouseState.MouseLeftDown:
                    return new ColorBlend()
                    {
                        Positions = new float[] { 0f, 0.40f, 1f },
                        Colors = new Color[] { colorRoot.ShiftColor(-0.50f * colorShift), colorRoot.ShiftColor(-0.10f * colorShift), colorRoot.ShiftColor(0.50f * colorShift) }
                    };
                case MouseState.None:
                case MouseState.Outside:
                default:
                    return new ColorBlend()
                    {
                        Positions = new float[] { 0f, 0.33f, 1f },
                        Colors = new Color[] { colorRoot.ShiftColor(0.60f * colorShift), colorRoot.ShiftColor(0.10f * colorShift), colorRoot.ShiftColor(-0.40f * colorShift) }
                    };
            }
        }

        private static ColorBlend GetColorBlendWinXpStyle(Color colorRoot, float colorShift, MouseState state)
        {
            switch (state)
            {
                case MouseState.OnControl:
                case MouseState.MouseRightDown:
                    return new ColorBlend()
                    {
                        Positions = new float[] { 0.0f, 0.5f, 0.5f, 1.0f },
                        Colors = new Color[] { colorRoot.ShiftColor(colorShift), colorRoot.ShiftColor(0.60f * colorShift), colorRoot.ShiftColor(0.20f * colorShift), colorRoot.ShiftColor(0.20f * colorShift) }
                    };
                case MouseState.MouseLeftDown:
                    return new ColorBlend()
                    {
                        Positions = new float[] { 0.0f, 0.45f, 0.45f, 1.0f },
                        Colors = new Color[] { colorRoot.ShiftColor(colorShift), colorRoot.ShiftColor(0.40f * colorShift), colorRoot.ShiftColor(-0.20f * colorShift), colorRoot.ShiftColor(-0.00f * colorShift) }
                    };
                case MouseState.None:
                case MouseState.Outside:
                default:
                    return new ColorBlend()
                    {
                        Positions = new float[] { 0.0f, 0.5f, 0.5f, 1.0f },
                        Colors = new Color[] { colorRoot.ShiftColor(colorShift), colorRoot.ShiftColor(0.40f * colorShift), colorRoot, colorRoot }
                    };
            }
        }

        private static ColorBlend GetColorBlendWin7Style(Color colorRoot, float colorShift, MouseState state)
        {
			switch (state)
			{
				case MouseState.OnControl:
				case MouseState.MouseRightDown:
					return new ColorBlend()
					{
						Positions = new float[] { 0.0f, 0.3f, 0.3f, 1.0f },
						Colors = new Color[] { colorRoot.ShiftColor(colorShift), colorRoot.ShiftColor(0.60f * colorShift), colorRoot.ShiftColor(0.20f * colorShift), colorRoot.ShiftColor(0.20f * colorShift) }
					};
				case MouseState.MouseLeftDown:
					return new ColorBlend()
					{
						Positions = new float[] { 0.0f, 0.25f, 0.25f, 1.0f },
						Colors = new Color[] { colorRoot.ShiftColor(colorShift), colorRoot.ShiftColor(0.40f * colorShift), colorRoot.ShiftColor(-0.20f * colorShift), colorRoot.ShiftColor(-0.00f * colorShift) }
					};
				case MouseState.None:
				case MouseState.Outside:
				default:
					return new ColorBlend()
					{
						Positions = new float[] { 0.0f, 0.3f, 0.3f, 1.0f },
						Colors = new Color[] { colorRoot.ShiftColor(colorShift), colorRoot.ShiftColor(0.40f * colorShift), colorRoot, colorRoot }
					};
			}
        }

        #endregion
    }
    /// <summary>
    /// Interface který předepisuje přítomnost property RenderStyle CurrentRenderStyle { get; }.
    /// </summary>
    public interface ICurrentRenderStyle
    {
        /// <summary>
        /// Aktuální RenderStyle tohoto controlu
        /// </summary>
        RenderStyle CurrentRenderStyle { get; }
    }
    /// <summary>
    /// Druh renderování controlu
    /// </summary>
    public enum RenderStyle
    {
        /// <summary>
        /// Zděděný od předka.
        /// Pokud bude tento typ zadán pro konkrétní renderování, použije se renderer FlatStyle.
        /// </summary>
        Inherited,
        /// <summary>
        /// Jednoduchý barevný přechod
        /// </summary>
        FlatStyle,
        /// <summary>
        /// 
        /// </summary>
        ProfessionalStyle,
        WinXpStyle,
        Win7Style
    }
    /// <summary>
    /// Statický stav myši
    /// </summary>
    public enum MouseState
    {
        None = 0,
        Outside,
        OnControl,
        MouseLeftDown,
        MouseRightDown
    }
    /// <summary>
    /// Dynamický stav myši, zohledňuje i přechody mezi stavy MouseState
    /// </summary>
    public enum MouseChangeState
    {
        /// <summary>Myš tu není</summary>
        None = 0,
        /// <summary>Myš přišla</summary>
        Enter,
        /// <summary>Myš se pohybuje nad prvkem (bez stisknutí jakéhokoli tlačítka)</summary>
        Move,
        /// <summary>Myš se právě stiskla, levý button</summary>
        LeftDown,
		/// <summary>Myš je stisknutá (levý button) a právě se začala hýbat (vyběhla z ohrádky).
		/// Bod, na kterém se myš stiskla, je uložen v args.MousePointFDown, 
		/// Bod na kterém se myš nyní nachází je uložen v args.MousePointF.</summary>
		LeftDragBegin,
		/// <summary>Myš je stisknutá (levý button) a hýbe se (začátek byl hlášen stavem LeftDragBegin)</summary>
        LeftDragMove,
		/// <summary>Myš se hýbala v režimu LeftDragMove, a nyní se zvedla. Konec přetahování.</summary>
		LeftDragEnd,
		/// <summary>Myš se právě uvolnila, levý button</summary>
        LeftUp,
        /// <summary>Myš se právě stiskla, pravý button</summary>
        RightDown,
        /// <summary>Myš se právě uvolnila, pravý button</summary>
        RightUp,
        /// <summary>Myš není stisknutá a opouští nás</summary>
        Leave
    }
}
